package com.qiyi.player.core.video.provider.actors.clientp2p
{
   import flash.events.EventDispatcher;
   import com.qiyi.player.core.IDestroy;
   import com.qiyi.player.core.player.coreplayer.ICorePlayer;
   import flash.utils.Dictionary;
   import com.qiyi.player.base.logging.ILogger;
   import com.qiyi.player.core.Config;
   import flash.utils.ByteArray;
   import flash.utils.clearTimeout;
   import com.qiyi.player.core.video.events.ClientP2PEvent;
   import flash.system.Capabilities;
   import flash.utils.setTimeout;
   import com.qiyi.player.base.logging.Log;
   
   public class ClientP2PEngine extends EventDispatcher implements IDestroy
   {
      
      public function ClientP2PEngine(param1:ICorePlayer) {
         this._log = Log.getLogger("com.qiyi.player.core.video.provider.actors.clientp2p.ClientP2PEngine");
         super();
         this._holder = param1;
         this._commandMap = new Dictionary();
         this._messager = new ClientP2PMessager();
         this._messager.addEventListener(ClientP2PEvent.Evt_Connected,this.onMessagerConnected);
         this._messager.addEventListener(ClientP2PEvent.Evt_ReceiveData,this.onMessagerReceiveData);
         this._messager.addEventListener(ClientP2PEvent.Evt_IOError,this.onMessagerIOError);
         this._messager.addEventListener(ClientP2PEvent.Evt_SecurityError,this.onMessagerSecurityError);
         this._messager.addEventListener(ClientP2PEvent.Evt_Close,this.onMessagerClose);
         this.registerCommandCallback();
      }
      
      private const HEARTBEAT_TIMEOUT_TIME:int = 5000;
      
      private var _holder:ICorePlayer;
      
      private var _messager:ClientP2PMessager;
      
      private var _commandMap:Dictionary;
      
      private var _bufferTime:int = 0;
      
      private var _heartbeatTimeout:uint = 0;
      
      private var _isFailed:Boolean = false;
      
      private var _log:ILogger;
      
      public function get isOpen() : Boolean {
         return this._messager.connected;
      }
      
      public function get isFailed() : Boolean {
         return this._isFailed;
      }
      
      public function get bufferTime() : int {
         return this._bufferTime;
      }
      
      public function open() : void {
         var _loc1_:uint = 0;
         if(!this.isOpen)
         {
            if(this.isWindows())
            {
               _loc1_ = ClientP2PCheck.checkPort();
               if(_loc1_ > 0)
               {
                  this._isFailed = false;
                  this._messager.connect(Config.CLIENT_P2P_IP,_loc1_);
               }
               else
               {
                  this._isFailed = true;
                  this._holder.runtimeData.openClientP2P = false;
               }
            }
            else
            {
               this._isFailed = true;
               this._holder.runtimeData.openClientP2P = false;
            }
         }
      }
      
      public function close() : void {
         this._messager.close();
         this._bufferTime = 0;
      }
      
      public function sendHeartbeat() : void {
         var _loc1_:ByteArray = this.createCommand("Heartbeat",this._holder.currentTime);
         this._messager.send(ClientP2PMessager.FLAG_TYPE_COMMAND,_loc1_);
      }
      
      public function sendSetMeta(param1:int, param2:int, param3:String) : void {
         var _loc4_:ByteArray = this.createCommand("SetMeta",param1,param2,param3);
         this._messager.send(ClientP2PMessager.FLAG_TYPE_COMMAND,_loc4_);
      }
      
      public function sendSetVRS(param1:String) : void {
         var _loc2_:ByteArray = this.createCommand("SetVRS",param1);
         this._messager.send(ClientP2PMessager.FLAG_TYPE_COMMAND,_loc2_);
      }
      
      public function sendStartLoad(param1:int) : void {
         var _loc2_:ByteArray = this.createCommand("StartLoad",param1);
         this._messager.send(ClientP2PMessager.FLAG_TYPE_COMMAND,_loc2_);
      }
      
      public function sendStopLoad() : void {
         var _loc1_:ByteArray = this.createCommand("StopLoad");
         this._messager.send(ClientP2PMessager.FLAG_TYPE_COMMAND,_loc1_);
      }
      
      public function destroy() : void {
         clearTimeout(this._heartbeatTimeout);
         this._heartbeatTimeout = 0;
         this._holder = null;
         this._messager.removeEventListener(ClientP2PEvent.Evt_Connected,this.onMessagerConnected);
         this._messager.removeEventListener(ClientP2PEvent.Evt_ReceiveData,this.onMessagerReceiveData);
         this._messager.removeEventListener(ClientP2PEvent.Evt_IOError,this.onMessagerIOError);
         this._messager.removeEventListener(ClientP2PEvent.Evt_SecurityError,this.onMessagerSecurityError);
         this._messager.removeEventListener(ClientP2PEvent.Evt_Close,this.onMessagerClose);
         this._messager.destroy();
      }
      
      private function isWindows() : Boolean {
         return Capabilities.version.indexOf("WIN") == 0;
      }
      
      private function createCommand(param1:String, ... rest) : ByteArray {
         var _loc7_:* = 0;
         var _loc8_:* = 0;
         var _loc3_:* = "<invoke name=\'" + param1 + "\' returntype=\'void\'><arguments>";
         var _loc4_:Array = rest;
         if((_loc4_) && _loc4_.length > 0)
         {
            _loc7_ = _loc4_.length;
            _loc8_ = 0;
            while(_loc8_ < _loc7_)
            {
               _loc3_ = _loc3_ + ("<string>" + encodeURI(rest[_loc8_]) + "</string>");
               _loc8_++;
            }
         }
         _loc3_ = _loc3_ + "</arguments></invoke>";
         var _loc5_:ByteArray = new ByteArray();
         _loc5_.writeUTFBytes(_loc3_);
         var _loc6_:ByteArray = new ByteArray();
         _loc6_.writeInt(_loc5_.length);
         _loc6_.writeBytes(_loc5_);
         return _loc6_;
      }
      
      private function registerCommandCallback() : void {
         this._commandMap["Heartbeat"] = this.callbackHeartbeat;
         this._commandMap["StartLoadOK"] = this.callbackStartLoadOK;
         this._commandMap["StopLoadOK"] = this.callbackStopLoadOK;
      }
      
      private function callbackHeartbeat(param1:XMLList) : void {
         clearTimeout(this._heartbeatTimeout);
         this._heartbeatTimeout = setTimeout(this.onHeartbeatTimeout,this.HEARTBEAT_TIMEOUT_TIME);
         var _loc2_:int = int(decodeURI(param1[0]));
         if(_loc2_ >= 0)
         {
            this._bufferTime = _loc2_;
         }
         var _loc3_:int = int(decodeURI(param1[1]));
         if(_loc3_ >= 0)
         {
            this._holder.runtimeData.currentAverageSpeed = _loc3_;
         }
         this.sendHeartbeat();
      }
      
      private function callbackStartLoadOK(param1:XMLList) : void {
         dispatchEvent(new ClientP2PEvent(ClientP2PEvent.Evt_Start_LoadOK));
      }
      
      private function callbackStopLoadOK(param1:XMLList) : void {
         dispatchEvent(new ClientP2PEvent(ClientP2PEvent.Evt_Stop_LoadOK));
      }
      
      private function onReceiveCommand(param1:Object) : void {
         var _loc3_:ByteArray = new ByteArray();
         _loc3_.writeBytes(ByteArray(param1.data),int(param1.start),int(param1.length));
         _loc3_.position = 0;
         var _loc4_:int = _loc3_.readInt();
         var _loc5_:String = _loc3_.readUTFBytes(_loc4_);
         var _loc6_:XML = new XML(_loc5_);
         var _loc7_:String = _loc6_.@name;
         var _loc8_:Function = this._commandMap[_loc7_] as Function;
         if(_loc8_ != null)
         {
            _loc8_(_loc6_.arguments[0].children());
         }
      }
      
      private function ononReceiveVideo(param1:Object) : void {
         dispatchEvent(new ClientP2PEvent(ClientP2PEvent.Evt_ReceiveVideo,param1));
      }
      
      private function onHeartbeatTimeout() : void {
         this._log.info("ClientP2PEngine heartbeat timeout!");
         this.onFailed();
      }
      
      private function onFailed() : void {
         ClientP2PCheck.clearPort();
         this._isFailed = true;
         this._holder.runtimeData.openClientP2P = false;
         dispatchEvent(new ClientP2PEvent(ClientP2PEvent.Evt_Failed));
      }
      
      private function onMessagerConnected(param1:ClientP2PEvent) : void {
         clearTimeout(this._heartbeatTimeout);
         this._heartbeatTimeout = setTimeout(this.onHeartbeatTimeout,this.HEARTBEAT_TIMEOUT_TIME);
         dispatchEvent(new ClientP2PEvent(ClientP2PEvent.Evt_Connected));
      }
      
      private function onMessagerReceiveData(param1:ClientP2PEvent) : void {
         var _loc2_:int = int(param1.data.flagType);
         switch(_loc2_)
         {
            case ClientP2PMessager.FLAG_TYPE_COMMAND:
               this.onReceiveCommand(param1.data);
               break;
            case ClientP2PMessager.FLAG_TYPE_VIDEO:
               this.ononReceiveVideo(param1.data);
               break;
         }
      }
      
      private function onMessagerIOError(param1:ClientP2PEvent) : void {
         this.onFailed();
      }
      
      private function onMessagerSecurityError(param1:ClientP2PEvent) : void {
         this.onFailed();
      }
      
      private function onMessagerClose(param1:ClientP2PEvent) : void {
         this.onFailed();
      }
   }
}
